package main

import (
	"fmt"
	"log"
	"net/rpc"

	"gitee.com/go-course/go12/skills/rpc/service"
)

func main() {
	c := NewHelloServiceClient()
	resp := &service.HelloResponse{}
	err := c.Hello(&service.HelloRequest{Name: "bob"}, resp)
	if err != nil {
		panic(err)
	}
	fmt.Print(resp.Message)
}

var (
	// 约束客户端
	// 本质也是发起RPC调用
	// client.Hello(req, resp)
	_ service.HelloService = (*HelloServiceClient)(nil)
)

func NewHelloServiceClient() *HelloServiceClient {
	// 建立网络连接，拨号(rpc server)
	// 首先是通过rpc.Dial拨号RPC服务, 建立连接
	conn, err := rpc.Dial("tcp", "localhost:1234")
	if err != nil {
		log.Fatal("dialing:", err)
	}
	return &HelloServiceClient{
		conn: conn,
	}
}

type HelloServiceClient struct {
	conn *rpc.Client
}

// 在客户端如何实现hello接口   rpc ---> server 来实现Hello能力
func (c *HelloServiceClient) Hello(
	in *service.HelloRequest,
	out *service.HelloResponse) error {

	// 怎么调用这个rpc server 暴露的对象的方法喃?
	// 通过call方法进行调用
	// Call(serviceMethod string, args any, reply any) error
	// serviceMethod: servivcename.fn

	// 服务端的接口被 HelloService 约束了, 直接传递就是可行的
	err := c.conn.Call("HelloService.Hello", in, out)
	if err != nil {
		return err
	}

	return nil
}
